package com.poker.service;

import com.poker.consts.Code;
import com.poker.entity.News;
import com.poker.entity.NewsContent;
import com.poker.repository.NewsContentRepository;
import com.poker.repository.NewsRepository;
import com.poker.util.Misc;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class NewsService {

    @Resource
    private NewsRepository repository;

    @Resource
    private NewsContentRepository contentRepository;

    public News getById(String id) { return addNewsContent(repository.getOne(id)); }

    @Transactional
    public void update(News news) {
        News oldNews = repository.getOne(news.getId());
        news.setCreateTime(oldNews.getCreateTime());
        news.setPublicTime(oldNews.getPublicTime());

        repository.saveAndFlush(news);

        if (news.getIsTop()) repository.updateIsTop(news.getId(), news.getNewsType());

        NewsContent content = contentRepository.findByNewsId(news.getId());
        content.setContent(news.getContent());
        contentRepository.saveAndFlush(content);
    }

    @Transactional
    public void deleteNewsAndContent(News news) {
        NewsContent content = contentRepository.findByNewsId(news.getId());
        contentRepository.delete(content);
        repository.delete(news);
    }

    @Transactional
    public void saveNewsAndContent(News news) {
        news.setPublicTime(new Date());
        news.setCreateTime(new Date());
        repository.save(news);

        if (news.getIsTop()) repository.updateIsTop(news.getId(), news.getNewsType());

        NewsContent content = new NewsContent();
        content.setContent(news.getContent());
        content.setNewsId(news.getId());
        contentRepository.save(content);
    }

    /**
     * @param: [page, size];
     * @return: org.springframework.data.domain.Page<News>;
     * @Description: 不带条件分页查询;
     */
    public Page<News> findNewsNoCriteria(Integer page, Integer size) {
        Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "createTime");

        return addProperty(repository.findAll(pageable));
    }

    /**
     * @param: [page, size, News];
     * @return: org.springframework.data.domain.Page<News>;
     * @Description: 带条件的分页查询;
     */
    public Page<News> findNewsCriteria(Integer page, Integer size, News news) {
        Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "createTime");

        return addProperty(repository.findAll((Specification<News>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            if (Misc.isNotEmpty(news.getTitle()))
                list.add(criteriaBuilder.equal(root.get("title").as(String.class), news.getTitle()));

            Predicate[] predicateArray = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(predicateArray));
        }, pageable));
    }

    private News addNewsContent(News news) {
        NewsContent content = contentRepository.findByNewsId(news.getId());
        news.setContent(content.getContent());
        return news;
    }

    private Page<News> addProperty(Page<News> pages) {
        for (News news: pages) { addProperty(news); }

        return pages;
    }

    private News addProperty(News news) {
        news.setNewsTypeName(Code.NewsType.get(news.getNewsType()));
        return news;
    }

}
